iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0

什麼是預掛單?

預掛單又稱代處理訂單,主要目的是在未來的某個價格水平達到時自動進行買入或賣出操作,而無需實時監控市場。

掛單的類型

  • 市價單(Market Order): 市價單是立即以市場上最好的可用價格執行的訂單。它確保了立即成交,但執行價格可能略有不同於訂單放置時的報價。

  • 限價單(Limit Order): 限價單是設置在特定價格水平上等待執行的訂單。當市場價格達到或超過您指定的價格時,限價單將被觸發,並以該價格或更好的價格執行。

  • 止損單(Stop Loss Order): 止損單是一種用於降低損失的訂單。它設置在比您購入或賣出價格低的水平上,以限制損失。當市場價格達到或低於止損價格時,該訂單將被觸發。

  • 止盈單(Take Profit Order): 止盈單是用於鎖定利潤的訂單。它設置在比您購入或賣出價格高的水平上,當市場價格達到或超過止盈價格時,該訂單將被觸發,以實現利潤。

  • 追蹤止損單(Trailing Stop Order): 追蹤止損單是一種動態訂單,其止損價格會隨著市場價格的變化而調整。當市場價格朝有利的方向移動時,追蹤止損價格也會相應調整,以鎖定利潤。

  • OCO(One-Cancels-the-Other)訂單: OCO訂單包含兩個相關的訂單,其中一個訂單的執行將自動取消另一個訂單。這通常用於設定同時的止損和止盈訂單。

  • GTC(Good 'Til Canceled)訂單: GTC訂單是一種長期有效的訂單,它將一直有效,直到特定條件滿足或投資者取消為止。

  • GTD(Good 'Til Date)訂單: GTD訂單是一種在特定日期前有效的訂單,無論市場是否達到訂單條件,該訂單在指定日期到期。

創建下單函數

這邊我們與下市價單時用一樣的方式創建一個OpenPending()函數用來下預掛單。

1° 在CTrade宣告函數

class CTrade
{
	private:
		MqlTradeRequest request;

		bool OpenPending(string pSymbol, ENUM_ORDER_TYPE pType, double pVolume, double pPrice, double pStop = 0, double pProfit = 0, double pStopLimit = 0, datetime pExpiration = 0, string pComment = NULL);
		
	public:
		MqlTradeResult result;
}

2°填充物件變數

bool CTrade::OpenPending(string pSymbol, ENUM_ORDER_TYPE pType, double pVolume, double pPrice, double pStop = 0, double pProfit = 0, double pStopLimit = 0, datetime pExpiration = 0, string pComment = NULL)
{
    request.action = TRADE_ACTION_PENDING;
    ...//以下與前幾篇文章下單函數相同方式,故省略
}

TRADE_ACTION_PENDING為指示下預掛單的常數。

3°確定到期時間

if(pExpiration > 0)
	{
		request.expiration = pExpiration;
		request.type_time = ORDER_TIME_SPECIFIED;
	}
	else request.type_time = ORDER_TIME_GTC;

跟下市價單不一樣,預掛單有可能會有時間上的限制,所以需要額外考慮關於時間設定方面的問題。
若有指定時間(即pExpiration > 0),將type_time設為ORDER_TIME_SPECIFIED,代表有指定的到期時間,若不指定到期時間則會設成不會過期。

4°錯誤與重試

下市價單那一篇已經有提到關於錯誤蟲式的部分,這邊就不再多做贅述。

int checkCode = 0;
int retryCount = 0;
int maxRetryCount = 3;
int retryDelay = 3000;

do 
	{
		OrderSend(request,result);
		
		checkCode = CheckReturnCode(result.retcode);
		
		if(checkCode == Trade_Success) break;
		else if(checkCode == Trade_Error)
		{
			string errDesc = TradeServerReturnCodeDescription(result.retcode);
			Alert("Open pending order: Error ",result.retcode," - ",errDesc);
			break;
		}
		else
		{
			Print("Server error detected, retrying...");
			Sleep(retryDelay);
			retryCount++;
		}
	}
	while(retryCount < maxRetryCount);

唯一的差別在於此處不需要檢查bid/ask價格。

剩下的程式碼便與OpenPosition()函數一樣了,像是將錯誤碼與掛單資訊輸出至交易日誌。
明天會來分享在寫完這東西後,要如何使用在EA裡面,畢竟目前寫的內容都還在Class中。


上一篇
DAY21 修改與平倉
下一篇
DAY23 用helper來簡化
系列文
從零開始的外匯自動程式交易30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言